package com.hejia.bulbul.service;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

import com.hejia.alauda.entity.Channel;
import com.hejia.alauda.entity.ChannelCount;
import com.hejia.alauda.entity.DayCount;
import com.hejia.alauda.entity.Popularize;
import com.hejia.alauda.entity.example.ChannelExample;
import com.hejia.alauda.persistence.mybatis.ChannelMapper;
import com.hejia.alauda.persistence.mybatis.PopularizeCategoryMapper;
import com.hejia.alauda.persistence.mybatis.PopularizeMapper;
import com.hejia.alauda.service.PopularizeService;
import com.hejia.alauda.utils.Pager;
import com.hejia.bulbul.entity.ChannelAnalyse;
import com.hejia.bulbul.entity.ChannelDayStatistic;
import com.hejia.bulbul.entity.ChannelStatistic;
import com.mongodb.AggregationOptions;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.Cursor;
import com.mongodb.DBObject;

@Service
public class ChannelStatisticServiceImpl implements ChannelStatisticService {

	@Resource
	private MongoTemplate mongoTemplate;
	
	@Resource
	private ChannelMapper channelMapper;
	
	@Resource
	private PopularizeCategoryMapper popularizeCategoryMapper;
	
	@Resource
	private PopularizeMapper popularizeMapper;
	
	@Resource
	private PopularizeService popularizeService;
	
	@Override
	public Pager<ChannelStatistic> statisticChannels(String name, Date startDate, Date endDate, Pager<ChannelStatistic> pager) {
		
		Pager<Channel> channelPager = new Pager<Channel>();
		channelPager.setPageSize(pager.getPageSize());
		channelPager.setPageNumber(pager.getPageNumber());
		
		ChannelExample example = new ChannelExample();
		example.setOrderByClause("createDate desc");
		if(StringUtils.isNotEmpty(name)){
			name = "%" + name + "%";
			example.appendCriterion("(name like '" + name + "' or " + "number like '" + name + "')");
		}
		
		List<ChannelStatistic> statistics = new ArrayList<ChannelStatistic>();
		List<Channel> channels = this.channelMapper.selectByExample(example, channelPager);
		for(Channel channel : channels){
			ChannelStatistic statistic = new ChannelStatistic();
			statistic.setChannel(channel);
			statistics.add(statistic);
		}
		
		if(statistics.size() > 0){
			setRegisterCount(statistics, startDate, endDate);
			setRealNameUserCount(statistics, startDate, endDate);
			setPaidUserCount(statistics, startDate, endDate);
			setOrderCount(statistics, startDate, endDate);
			setPaidOrderCount(statistics, startDate, endDate);
			setPaymentAmountCount(statistics, startDate, endDate);
		}
		
		pager.setList(statistics);
		pager.setTotalCount(this.channelMapper.countByExample(example));
		
		return pager;
	}

	/**
	 * 设置下单支付金额
	 * @param statistics	统计列表
	 * @param startDate		开始时间
	 * @param endDate		结束时间
	 */
	private void setPaymentAmountCount(
			List<ChannelStatistic> statistics,
			Date startDate, 
			Date endDate) {
		
		Map<String, Object> map = createCountMap(statistics, startDate, endDate);
		List<ChannelCount> counts = this.channelMapper.countPaymentAmountByChannelsAndDate(map);
		
		for(ChannelCount count : counts){
			for(ChannelStatistic statistic : statistics){
				if(statistic.getChannel().getNumber().equals(count.getReferee())){
					statistic.setPaymentAmount(count.getAmount());
					break;
				}
			}
		}
		
	}
	
	/**
	 * 设置支付订单数
	 * @param statistics	统计列表
	 * @param startDate		开始时间
	 * @param endDate		结束时间
	 */
	private void setPaidOrderCount(
			List<ChannelStatistic> statistics,
			Date startDate, 
			Date endDate) {
		
		Map<String, Object> map = createCountMap(statistics, startDate, endDate);
		List<ChannelCount> counts = this.channelMapper.countPaidOrderByChannelsAndDate(map);
		
		for(ChannelCount count : counts){
			for(ChannelStatistic statistic : statistics){
				if(statistic.getChannel().getNumber().equals(count.getReferee())){
					statistic.setPaidOrderCount(count.getCount());
					break;
				}
			}
		}
		
	}
	
	/**
	 * 设置下单数
	 * @param statistics	统计列表
	 * @param startDate		开始时间
	 * @param endDate		结束时间
	 */
	private void setOrderCount(
			List<ChannelStatistic> statistics,
			Date startDate, 
			Date endDate) {
		
		Map<String, Object> map = createCountMap(statistics, startDate, endDate);
		List<ChannelCount> counts = this.channelMapper.countOrderByChannelsAndDate(map);
		
		for(ChannelCount count : counts){
			for(ChannelStatistic statistic : statistics){
				if(statistic.getChannel().getNumber().equals(count.getReferee())){
					statistic.setOrderCount(count.getCount());
					break;
				}
			}
		}
		
	}
	
	/**
	 * 设置下单支付用户数
	 * @param statistics	统计列表
	 * @param startDate		开始时间
	 * @param endDate		结束时间
	 */
	private void setPaidUserCount(
			List<ChannelStatistic> statistics,
			Date startDate, 
			Date endDate) {
		
		Map<String, Object> map = createCountMap(statistics, startDate, endDate);
		List<ChannelCount> counts = this.channelMapper.countPaidUserByChannelsAndDate(map);
		
		for(ChannelCount count : counts){
			for(ChannelStatistic statistic : statistics){
				if(statistic.getChannel().getNumber().equals(count.getReferee())){
					statistic.setPaidUserCount(count.getCount());
					break;
				}
			}
		}
		
	}

	/**
	 * 设置实名认证用户数
	 * @param statistics	统计列表
	 * @param startDate		开始时间
	 * @param endDate		结束时间
	 */
	private void setRealNameUserCount(
			List<ChannelStatistic> statistics,
			Date startDate, 
			Date endDate) {
		
		Map<String, Object> map = createCountMap(statistics, startDate, endDate);
		List<ChannelCount> counts = this.channelMapper.countRealNameUserByChannelsAndDate(map);
		
		for(ChannelCount count : counts){
			for(ChannelStatistic statistic : statistics){
				if(statistic.getChannel().getNumber().equals(count.getReferee())){
					statistic.setRealNameCount(count.getCount());
					break;
				}
			}
		}
		
	}

	/**
	 * 设置注册数
	 * @param statistics	统计列表
	 * @param startDate		开始时间
	 * @param endDate		结束时间
	 */
	private void setRegisterCount(List<ChannelStatistic> statistics, Date startDate, Date endDate) {
		
		Map<String, Object> map = createCountMap(statistics, startDate, endDate);
		List<ChannelCount> counts = this.channelMapper.countRegisterByChannelsAndDate(map);
		
		for(ChannelCount count : counts){
			for(ChannelStatistic statistic : statistics){
				if(statistic.getChannel().getNumber().equals(count.getReferee())){
					statistic.setRegisterCount(count.getCount());
					break;
				}
			}
		}
	}

	/**
	 * 创建统计映射参数
	 * @param statistics	统计列表
	 * @param startDate		开始时间
	 * @param endDate		结束时间
	 * @return
	 */
	private Map<String, Object> createCountMap(
			List<ChannelStatistic> statistics, 
			Date startDate, 
			Date endDate) {
		
		DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Map<String, Object> map = new HashMap<String, Object>();
		List<String> numbers = createChannelNumbers(statistics);
		map.put("numbers", numbers);
		map.put("startDate", format.format(startDate));
		map.put("endDate", format.format(endDate));
		
		return map;
	}

	/**
	 * 创建渠道号列表
	 * @param statistics
	 * @return	渠道号列表
	 */
	private List<String> createChannelNumbers(List<ChannelStatistic> statistics) {
		 List<String> numbers = new ArrayList<String>();
		 for(ChannelStatistic statistic : statistics){
			 numbers.add(statistic.getChannel().getNumber());
		 }
		 return numbers;
	}

	@Override
	public ChannelAnalyse analyseChannel(
			Long biggerCategoryId, 
			Long categoryId, 
			Long popularizeId,
			String number,
			Date startDate, 
			Date endDate){
		
		ChannelAnalyse channelAnalyse = new ChannelAnalyse();
		channelAnalyse.setChannelNumber(number);
		
		List<String> numbers = new ArrayList<>();
		if (biggerCategoryId != null) {
			numbers = popularizeService.findSourceIdByBiggerCategoryId(biggerCategoryId);
			channelAnalyse.setName(popularizeService.findCategoryById(biggerCategoryId).getName());
			channelAnalyse.setVisitCount(this.channelMapper
					.countVisitIPByBiggerCategoryIdAndDate(biggerCategoryId, startDate, endDate));
		} else if (categoryId != null) {
			numbers = popularizeService.findSourceIdByCategoryId(categoryId);
			channelAnalyse.setName(popularizeService.findCategoryById(categoryId).getName());
			channelAnalyse.setVisitCount(this.channelMapper
					.countVisitIPByCategoryIdAndDate(categoryId, startDate, endDate));
		} else if (popularizeId != null) {
			numbers = popularizeService.findSourceIdByPopularizeId(popularizeId);
			channelAnalyse.setName(popularizeService.findById(popularizeId).getName());
			channelAnalyse.setVisitCount(this.channelMapper
					.countVisitIPByPopularizeIdAndDate(popularizeId, startDate, endDate));
		} else if (StringUtils.isNotEmpty(number)) {
			numbers.add(number);
			Channel channel = findChannelByNumber(number);
			channelAnalyse.setName(channel.getName());
		}
		
		channelAnalyse.setRegisterCount(this.channelMapper.countRegisterByChannelNumberAndDate(numbers, startDate, endDate));
		channelAnalyse.setRealNameCount(this.channelMapper.countRealNameByChannelNumberAndDate(numbers, startDate, endDate));
		channelAnalyse.setOrderCount(this.channelMapper.countOrderByChannelNumberAndDate(numbers, startDate, endDate));
		channelAnalyse.setPaidOrderCount(this.channelMapper.countPaidOrderByChannelNumberAndDate(numbers, startDate, endDate));
		channelAnalyse.setPaymentAmount(this.channelMapper.countPaymentAmountByChannelNumberAndDate(numbers, startDate, endDate));
		channelAnalyse.setPaidUserCount(this.channelMapper.countPaidUserByChannelNumberAndDate(numbers, startDate, endDate));
		channelAnalyse.setRepeatOrderUserCount(this.channelMapper.countRepeatOrderUserByChannelNumberAndDate(numbers, startDate, endDate));
		channelAnalyse.setRepeatOrderCount(this.channelMapper.countRepeatOrderByChannelNumberAndDate(numbers, startDate, endDate));
		channelAnalyse.setRepeatOrderAmount(this.channelMapper.countRepeatOrderAmountByChannelNumberAndDate(numbers, startDate, endDate));
		channelAnalyse.setRepeatUserOrderCount(this.channelMapper.countRepeatUserOrderByChannelNumberAndDate(numbers, startDate, endDate));
		channelAnalyse.setRegisterUserOrderCount(this.channelMapper.countRegisterUserOrderByChannelNumberAndDate(numbers, startDate, endDate));
		channelAnalyse.setRegisterUserPaidOrderCount(this.channelMapper.countRegisterUserPaidOrderByChannelNumberAndDate(numbers, startDate, endDate));
		channelAnalyse.setRegisterUserPaymentAmount(this.channelMapper.countRegisterUserPaymentAmountByChannelNumberAndDate(numbers, startDate, endDate));
		channelAnalyse.setRegisterPaidUserCount(this.channelMapper.countRegisterPaidUserByChannelNumberAndDate(numbers, startDate, endDate));
		channelAnalyse.setRegisterTradeUserCount(this.channelMapper.countRegisterTradeUserByChannelNumberAndDate(numbers, startDate, endDate));
		channelAnalyse.setNewTradeUserCount(this.channelMapper.countNewTradeUserByChannelNumberAndDate(numbers, startDate, endDate));
		channelAnalyse.setNewTradeOrderAmount(this.channelMapper.countNewTradeOrderAmountByChannelNumberAndDate(numbers, startDate, endDate));
		return channelAnalyse;
	}

	/**
	 * 统计渠道的访问数量
	 * @param numbers
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	private Long countVisitByChannelNumberAndDate(List<String> numbers, Date startDate, Date endDate) {
		
		BasicDBList numberList = new BasicDBList();
	    for (String number : numbers) {
	    	numberList.add(number);
	    }
	    
		DBObject createDateCondition = new BasicDBObject("$gte", startDate);
		createDateCondition.put("$lte", endDate);
		DBObject matchCondition = new BasicDBObject("createDate", createDateCondition);
		matchCondition.put("sourceId", new BasicDBObject("$in", numberList));
		DBObject match = new BasicDBObject("$match", matchCondition);

		// 按天去重相同IP数据
		DBObject dayGroup = createDayGroup();
		
		DBObject groupFields = new BasicDBObject("_id", null);
		groupFields.put("count", new BasicDBObject("$sum", 1));
		DBObject group = new BasicDBObject("$group", groupFields);

		List<DBObject> pipeline = Arrays.asList(match, dayGroup, group);
		
		AggregationOptions options = AggregationOptions.builder()
		        .batchSize(100)
		        .outputMode(AggregationOptions.OutputMode.CURSOR)
		        .allowDiskUse(true)
		        .build();
		
		Cursor cursor = this.mongoTemplate.getCollection(
				"popularizeVisit").aggregate(pipeline, options);
		
		Long count = 0L;
		while (cursor.hasNext()) {
			DBObject value = cursor.next();
			count = Long.parseLong(value.get("count").toString());
		}
		
		return count;
	}
	
	/**
	 * 创建按天分组对象
	 * 按天去重相同IP数据
	 * @return	按天分组对象
	 */
	private DBObject createDayGroup() {

		DBObject dayGroupFields = new BasicDBObject("visitorIP", "$visitorIP");
		dayGroupFields.put("popularizeId", "$popularizeId");
		dayGroupFields.put("year", new BasicDBObject("$year", "$createDate"));
		dayGroupFields.put("month", new BasicDBObject("$month", "$createDate"));
		dayGroupFields.put("day", new BasicDBObject("$dayOfMonth", "$createDate"));
		DBObject dayGroupIdField = new BasicDBObject("_id", dayGroupFields);
		DBObject dayGroup = new BasicDBObject("$group", dayGroupIdField);
		return dayGroup;
	}

	private Channel findChannelByNumber(String number) {
		
		ChannelExample example = new ChannelExample();
		example.appendCriterion("number =", number);
		return this.channelMapper.selectOneByExample(example);
	}

	@Override
	public Pager<ChannelStatistic> statisticRegister(String name, Date startDate, Date endDate, Pager<ChannelStatistic> pager) {
		
		List<ChannelStatistic> statistics = new ArrayList<ChannelStatistic>();
		Map<String, Object> map = new HashMap<>();
		if(StringUtils.isEmpty(name)){
			name = "";
		}
		map.put("name", "%" + name + "%");
		map.put("startDate", startDate);
		map.put("endDate", endDate);
		map.put("pageSize", pager.getPageSize());
		map.put("startNumber", pager.getStartNumber());
		List<ChannelCount> channelCounts = this.channelMapper.countRegisterByChannelNameAndDate(map);
		
		for(ChannelCount channelCount : channelCounts){
			ChannelStatistic statistic = new ChannelStatistic();
			Channel channel = new Channel();
			channel.setNumber(channelCount.getReferee());
			statistic.setChannel(channel);
			statistic.setRegisterCount(channelCount.getCount());
			statistics.add(statistic);
		}
		
		setChannelNames(statistics);
		
		if(statistics.size() > 0){
			setRealNameUserCount(statistics, startDate, endDate);
			setPaidUserCount(statistics, startDate, endDate);
			setOrderCount(statistics, startDate, endDate);
			setPaidOrderCount(statistics, startDate, endDate);
			setPaymentAmountCount(statistics, startDate, endDate);
		}
		
		pager.setList(statistics);
		pager.setTotalCount(this.channelMapper.countChannelByChannelNameAndDate(map));
		
		return pager;
	}

	/**
	 * 设置渠道名称
	 * @param statistics
	 */
	private void setChannelNames(List<ChannelStatistic> statistics) {
		
		List<Long> popularizeIds = new ArrayList<>();
		List<String> channelNumbers = new ArrayList<>();
		for(ChannelStatistic statistic : statistics){
			String number = statistic.getChannel().getNumber();
			if(number.startsWith("P:")){
				popularizeIds.add(parsePopularizeId(number));
			}else{
				channelNumbers.add(number);
			}
		}
		
		if(popularizeIds.size() > 0){
			List<Popularize> popularizes = this.popularizeMapper.selectByIds(popularizeIds.toArray(new Long[0]));
			for(Popularize popularize : popularizes){
				for(ChannelStatistic statistic : statistics){
					if(popularize.getSourceId().endsWith(statistic.getChannel().getNumber())){
						statistic.getChannel().setName(popularize.getName());
						break;
					}
				}
			}
		}
		
		if(channelNumbers.size() > 0){
			ChannelExample example = new ChannelExample();
			example.appendCriterion("number in", channelNumbers);
			Pager<Channel> pager = new Pager<>();
			pager.setPageSize(100);
			List<Channel> channels = this.channelMapper.selectByExample(example, pager);
			for(Channel channel : channels){
				for(ChannelStatistic statistic : statistics){
					if(channel.getNumber().endsWith(statistic.getChannel().getNumber())){
						statistic.getChannel().setName(channel.getName());
						break;
					}
				}
			}
		}
	}

	/**
	 * 解析推广ID
	 * @param sourceId
	 * @return
	 */
	private Long parsePopularizeId(String sourceId) {
		String[] items = sourceId.split("-");
		return Long.parseLong(items[2]);
	}

	@Override
	public List<ChannelDayStatistic> countChannelDailyData(
			Long biggerCategoryId, 
			Long categoryId, 
			Long popularizeId, 
			String number,
			Date startDate, 
			Date endDate) {
		
		Date date = new DateTime(startDate).minusMillis(1).toDate();
		List<ChannelDayStatistic> statistics = createChannelDayStatistics(startDate, endDate);
		
		List<String> numbers = new ArrayList<>();
		if (biggerCategoryId != null) {
			numbers = popularizeService.findSourceIdByBiggerCategoryId(biggerCategoryId);
		} else if (categoryId != null) {
			numbers = popularizeService.findSourceIdByCategoryId(categoryId);
		} else if (popularizeId != null) {
			numbers = popularizeService.findSourceIdByPopularizeId(popularizeId);
		} else if (StringUtils.isNotEmpty(number)) {
			numbers.add(number);
		}
		
		setDailyRegisterCount(statistics, this.channelMapper.countDailyRegisterByChannelAndDate(numbers, startDate, endDate));
		setDailyAllRegisterCount(statistics, this.channelMapper.countDailyAllRegisterByChannelAndDate(startDate, endDate));
		setDailyNewTradeUserCount(statistics, this.channelMapper.countDailyNewTradeUserByChannelAndDate(numbers, startDate, endDate));
		setDailyAllNewTradeUserCount(statistics, this.channelMapper.countDailyAllNewTradeUserByChannelAndDate(startDate, endDate));
		setDailyAccumulativeRegisterCount(statistics, this.channelMapper.countAccumulativeRegisterByChannelAndDate(numbers, date));
		setDailyAccumulativeTradeUserCount(statistics, this.channelMapper.countAccumulativeTradeUserByChannelAndDate(numbers, date));
		setDailyAllAccumulativeTradeUserCount(statistics, this.channelMapper.countAllAccumulativeTradeUserByChannelAndDate(date));
		setDailyTradeAmount(statistics, this.channelMapper.countDailyTradeAmountByChannelAndDate(numbers, startDate, endDate));
		setDailyAllTradeAmount(statistics, this.channelMapper.countDailyAllTradeAmountByChannelAndDate(startDate, endDate));
		setDailyAccumulativeTradeAmount(statistics, this.channelMapper.countAccumulativeTradeAmountByChannelAndDate(numbers, date));
		setDailyAllNewAppTradeUser(statistics, this.channelMapper.countDailyAllNewAppTradeUserCountByChannelAndDate(startDate, endDate));
		setDailyAccumulativeAppTradeUserCount(statistics,
				this.channelMapper.countAccumulativeAppTradeUserCountByChannelAndDate(numbers, date),
				this.channelMapper.countDailyNewAppTradeUserCountByChannelAndDate(numbers, startDate, endDate));
		
		return statistics;
	}

	/**
	 * 设置所有渠道每日新增App交易用户数
	 * @param statistics	统计列表
	 * @param dayCounts		所有渠道日新增App交易用户数
	 */
	private void setDailyAllNewAppTradeUser(List<ChannelDayStatistic> statistics, List<DayCount> dayCounts) {
		for(ChannelDayStatistic statistic : statistics){
			for(DayCount dayCount : dayCounts){
				if(dayCount.getDate().compareTo(statistic.getDate()) == 0){
					statistic.setAllNewAppTradeUserCount(dayCount.getCount());
					break;
				}
			}
		}
	}

	/**
	 * 设置每日渠道App累计交易用户数
	 * @param statistics	统计列表
	 * @param accumulativeAppTradeUserCount
	 * @param countDailyAppTradeUserCountByChannelAndDate
	 */
	private void setDailyAccumulativeAppTradeUserCount(List<ChannelDayStatistic> statistics, Long accumulativeAppTradeUserCount, List<DayCount> dayCounts) {
		for(ChannelDayStatistic statistic : statistics){
			statistic.setAccumulativeAppTradeUserCount(accumulativeAppTradeUserCount);
			for(DayCount dayCount : dayCounts){
				if(dayCount.getDate().compareTo(statistic.getDate()) == 0){
					statistic.setNewAppTradeUserCount(dayCount.getCount());
				}
				if(dayCount.getDate().compareTo(statistic.getDate()) <= 0){
					statistic.setAccumulativeAppTradeUserCount(statistic.getAccumulativeAppTradeUserCount() + dayCount.getCount());
				}
			}
		}
	}

	/**
	 * 设置每日渠道累计交易金额
	 * @param statistics	统计列表
	 * @param accumulativeTradeAmount	道累计交易金额
	 */
	private void setDailyAccumulativeTradeAmount(List<ChannelDayStatistic> statistics, BigDecimal accumulativeTradeAmount) {
		for(ChannelDayStatistic statistic : statistics){
			statistic.setAccumulativeTradeAmount(accumulativeTradeAmount);
			for(ChannelDayStatistic statistic2 : statistics){
				if(statistic.getDate().compareTo(statistic2.getDate()) >= 0){
					statistic.setAccumulativeTradeAmount(
							statistic.getAccumulativeTradeAmount().add(statistic2.getTradeAmount()));
				}
			}
		}
	}

	/**
	 * 设置每日所有渠道交易金额
	 * @param statistics	统计列表
	 * @param dayCounts	所有渠道日交易金额
	 */
	private void setDailyAllTradeAmount(List<ChannelDayStatistic> statistics, List<DayCount> dayCounts) {
		for(ChannelDayStatistic statistic : statistics){
			for(DayCount dayCount : dayCounts){
				if(dayCount.getDate().compareTo(statistic.getDate()) == 0){
					statistic.setAllTradeAmount(dayCount.getAmount());
					break;
				}
			}
		}
	}

	/**
	 * 设置每日渠道交易金额
	 * @param statistics	统计列表
	 * @param dayCounts	渠道日交易金额
	 */
	private void setDailyTradeAmount(List<ChannelDayStatistic> statistics, List<DayCount> dayCounts) {
		for(ChannelDayStatistic statistic : statistics){
			for(DayCount dayCount : dayCounts){
				if(dayCount.getDate().compareTo(statistic.getDate()) == 0){
					statistic.setTradeAmount(dayCount.getAmount());
					break;
				}
			}
		}
	}

	/**
	 * 设置每日所有渠道累计交易用户数
	 * @param statistics	统计列表
	 * @param allAccumulativeTradeUsercount	所有渠道累计交易用户数
	 */
	private void setDailyAllAccumulativeTradeUserCount(List<ChannelDayStatistic> statistics, Long allAccumulativeTradeUsercount) {
		for(ChannelDayStatistic statistic : statistics){
			statistic.setAllAccumulativeTradeUserCount(allAccumulativeTradeUsercount);
			for(ChannelDayStatistic statistic2 : statistics){
				if(statistic.getDate().compareTo(statistic2.getDate()) >= 0){
					statistic.setAllAccumulativeTradeUserCount(
							statistic.getAllAccumulativeTradeUserCount() + statistic2.getAllNewTradeUserCount());
				}
			}
		}
	}

	/**
	 * 设置每日渠道累计交易用户数
	 * @param statistics	统计列表
	 * @param accumulativeTradeUserCount	累计交易用户数
	 */
	private void setDailyAccumulativeTradeUserCount(List<ChannelDayStatistic> statistics, Long accumulativeTradeUserCount) {
		for(ChannelDayStatistic statistic : statistics){
			statistic.setAccumulativeTradeUserCount(accumulativeTradeUserCount);
			for(ChannelDayStatistic statistic2 : statistics){
				if(statistic.getDate().compareTo(statistic2.getDate()) >= 0){
					statistic.setAccumulativeTradeUserCount(
							statistic.getAccumulativeTradeUserCount() + statistic2.getNewTradeUserCount());
				}
			}
		}
	}

	/**
	 * 设置每日渠道累计注册用户数
	 * @param statistics	统计列表
	 * @param accumulativeRegisterCount	累计注册用户数
	 */
	private void setDailyAccumulativeRegisterCount(List<ChannelDayStatistic> statistics, Long accumulativeRegisterCount) {
		for(ChannelDayStatistic statistic : statistics){
			statistic.setAccumulativeRegisterCount(accumulativeRegisterCount);
			for(ChannelDayStatistic statistic2 : statistics){
				if(statistic.getDate().compareTo(statistic2.getDate()) >= 0){
					statistic.setAccumulativeRegisterCount(
							statistic.getAccumulativeRegisterCount() + statistic2.getRegisterCount());
				}
			}
		}
	}

	/**
	 * 设置每日所有渠道新增交易用户数
	 * @param statistics	统计列表
	 * @param dayCounts		日统计数据列表
	 */
	private void setDailyAllNewTradeUserCount(List<ChannelDayStatistic> statistics, List<DayCount> dayCounts) {
		for(ChannelDayStatistic statistic : statistics){
			for(DayCount dayCount : dayCounts){
				if(dayCount.getDate().compareTo(statistic.getDate()) == 0){
					statistic.setAllNewTradeUserCount(dayCount.getCount());
					break;
				}
			}
		}
	}

	/**
	 * 设置每日渠道新增交易用户数
	 * @param statistics	统计列表
	 * @param dayCounts		日统计数据列表
	 */
	private void setDailyNewTradeUserCount(List<ChannelDayStatistic> statistics, List<DayCount> dayCounts) {
		for(ChannelDayStatistic statistic : statistics){
			for(DayCount dayCount : dayCounts){
				if(dayCount.getDate().compareTo(statistic.getDate()) == 0){
					statistic.setNewTradeUserCount(dayCount.getCount());
					break;
				}
			}
		}
	}

	/**
	 * 设置每日所有渠道注册用户数
	 * @param statistics	统计列表
	 * @param dayCounts		日统计数据列表
	 */
	private void setDailyAllRegisterCount(List<ChannelDayStatistic> statistics, List<DayCount> dayCounts) {
		for(ChannelDayStatistic statistic : statistics){
			for(DayCount dayCount : dayCounts){
				if(dayCount.getDate().compareTo(statistic.getDate()) == 0){
					statistic.setAllRegisterCount(dayCount.getCount());
					break;
				}
			}
		}
	}

	/**
	 * 设置每日注册用户数
	 * @param statistics	统计列表
	 * @param dayCounts		日统计数据列表
	 */
	private void setDailyRegisterCount(List<ChannelDayStatistic> statistics, List<DayCount> dayCounts) {
		for(ChannelDayStatistic statistic : statistics){
			for(DayCount dayCount : dayCounts){
				if(dayCount.getDate().compareTo(statistic.getDate()) == 0){
					statistic.setRegisterCount(dayCount.getCount());
					break;
				}
			}
		}
	}

	/**
	 * 创建渠道日统计列表
	 * @param startDate	开始日期
	 * @param endDate	结束日期
	 * @return			渠道日统计列表
	 */
	private List<ChannelDayStatistic> createChannelDayStatistics(Date startDate, Date endDate) {
		
		startDate = new DateTime(startDate).toLocalDate().toDate();
		endDate = new DateTime(endDate).toLocalDate().toDate();
		
		List<ChannelDayStatistic> statistics = new ArrayList<>();
		
		Date date = startDate;
		while(date.compareTo(endDate) <= 0){
			ChannelDayStatistic statistic = new ChannelDayStatistic();
			statistic.setDate(date);
			statistics.add(statistic);
			date = new DateTime(date).plusDays(1).toDate();
		};
		
		return statistics;
	}

	@Override
	public String findChannelName(
			Long biggerCategoryId, 
			Long categoryId, 
			Long popularizeId, 
			String number) {
		
		if (biggerCategoryId != null) {
			return popularizeService.findCategoryById(biggerCategoryId).getName();
		} else if (categoryId != null) {
			return popularizeService.findCategoryById(categoryId).getName();
		} else if (popularizeId != null) {
			return popularizeService.findById(popularizeId).getName();
		} else if (StringUtils.isNotEmpty(number)) {
			Channel channel = findChannelByNumber(number);
			return channel.getName();
		}
		
		return "";
	}
}
